package com.lh.api.aspect;


import com.lh.common.enums.EventType;
import com.lh.common.utils.HttpUtil;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.json.JSONObject;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * @ClassName: OrderAspect
 * @Description: 给orderPayCallback和order/verifyPay接口加上切面，防止并发，同时修改数据库
 * @author wg
 *
 */
@Aspect
@Component
@Slf4j
public class OrderAspect {
    private static final Lock LOCK = new ReentrantLock();

    @Pointcut("@annotation(com.lh.api.annotation.OrderAnnotation)")
    public void methodCut() {
        //返回切点
    }

    @Around("methodCut()")
    public Object doAround(ProceedingJoinPoint joinPoint) throws Throwable {
        Object result = null;
        //获取当前请求对象
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = attributes.getRequest();
        JSONObject jsonObject = new JSONObject( HttpUtil.getRequestString(request));
        if(request.getRequestURI().contains("verifyPay") ||
                (jsonObject.has("event") && EventType.payment_captured.getValue().equals(jsonObject.get("event").toString()))  ){//如果是支付成功回调或者是调用了order/verifyPay方法才加锁
            LOCK.lock();
            try {
                result = joinPoint.proceed();
            } catch (Exception e) {
                log.error("Exception:",e);
                throw  e;
            } finally {
                LOCK.unlock();
            }

        }

        return result;
    }
}
